# /**
# * Copyright (c) 2022 Beijing Jiaotong University
# * PhotLab is licensed under [Open Source License].
# * You can use this software according to the terms and conditions of the [Open Source License].
# *
# * You may obtain a copy of [Open Source License] at: [https://open.source.license/]
# *
# * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
# * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
# * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
# *
# * See the [Open Source License] for more details.
# */
# /**
# * Author: Shihao Xie
# * Created: Aug. 31, 2022
# * Supported by: National Key Research and Development Program of China
# */

import gettext

from phot_server.server_config.global_config import SERVER_TYPE
from phot_server.core.api_injector import api
from phot_server.manager.project_manager import ProjectManager
from phot_server.rpc.project_service.Project import Processor
from phot_server.utils.phot_logger import logger

LOCAL_INTERFACE_FLAG = True if str.upper(SERVER_TYPE) == str.upper("Local") else False
REMOTE_INTERFACE_FLAG = True if str.upper(SERVER_TYPE) == str.upper("Remote") else False


# gettext instructions
# D:/Python/Tools/i18n/
# pygettext.py -d project -o locales/project.pot service/project_service.py
# msgfmt.py -o ./locales/cn/LC_MESSAGES/project.mo ./locales/cn/LC_MESSAGES/project
# msgfmt.py -o ./locales/en/LC_MESSAGES/project.mo ./locales/en/LC_MESSAGES/project

class ProjectService:
    """
    该服务是仿真项目相关服务，可以通过这个服务管理用户拥有的仿真项目及相关文件。
    调用该服务前，请确认已经做过连接服务相关操作并成功连接。例如：

    Examples:
        >>> from thrift import Thrift
        >>> from thrift.transport import TSocket
        >>> from thrift.transport import TTransport
        >>> from thrift.protocol import TBinaryProtocol
        >>> from photlab.project_service.Project import Client as project_client
        >>> transport = TSocket.TSocket("localhost", 8080)
        >>> transport_protocol = TTransport.TBufferedTransport(transport)
        >>> protocol_factory = TBinaryProtocol.TBinaryProtocol(transport_protocol)
        >>> project_client = project_client(protocol_factory)
        >>> transport.open()

    具体使用可以查看测试用例 test/test_interface/test_project.py
    """
    def __init__(self):
        self.project_manager = ProjectManager()

    @api(Processor.process_open_directory, LOCAL_INTERFACE_FLAG)
    def open_directory(self, directory_path):
        """
        打开一个文件夹。

        Args:
            directory_path (string): 文件夹路径

        Returns:
            list<PhotFile>: 文件列表

        Raises:
            PhotError: 异常代码查看PhotError的exception_code

        Examples:
            >>> project_client.open_directory("C://user//phot_project")
        """
        return self.project_manager.open_directory(directory_path)

    @api(Processor.process_open_file, LOCAL_INTERFACE_FLAG)
    def open_file(self, file_path):
        """
        打开文件。

        Args:
            file_path (string): 文件路径

        Returns:
            PhotFile: 文件对象

        Raises:
            PhotError: 异常代码查看PhotError的exception_code

        Examples:
            >>> project_client.open_file("C://user//phot_project//graph_1.phtg")
        """
        return self.project_manager.open_file(file_path)

    @api(Processor.process_new_project, LOCAL_INTERFACE_FLAG)
    def new_project(self, project_path, project_name, project_type):
        """
        新建仿真项目。

        Args:
            project_path: 项目路径
            project_name: 项目名称
            project_type: 项目类型

        Returns:
            ProjectConfig: 项目配置信息

        Raises:
            PhotError: 异常代码查看PhotError的exception_code

        Examples:
            >>> from photlab.project_data_type.ttypes import ProjectType
            >>> project_client.new_project("C://user//new_project", "new project", ProjectType.Optical_fiber_communication_simulation)
        """
        return self.project_manager.new_project(project_path, project_name, project_type)

    @api(Processor.process_open_project, LOCAL_INTERFACE_FLAG)
    def open_project(self, project_path):
        """
        打开一个仿真项目。服务端加载仿真项目配置并保存。

        Args:
            project_path: 项目路径

        Returns:
            ProjectConfig: 项目配置信息

        Raises:
            PhotError: 异常代码查看PhotError的exception_code

        Examples:
            >>> project_client.open_project("C://user//new_project")
        """
        return self.project_manager.open_project(project_path)

    @api(Processor.process_close_project, LOCAL_INTERFACE_FLAG)
    def close_project(self, project_id, window_config):
        """
        关闭仿真项目。服务端保存并删除相关仿真项目配置。

        Args:
            project_id: 项目名称
            window_config: 前端窗口配置

        Returns:
            无

        Raises:
            PhotError: 异常代码查看PhotError的exception_code

        Examples:
            >>> project_client.close_project("new_project", "")
        """
        self.project_manager.close_project(project_id, window_config)

    @api(Processor.process_refresh_project, LOCAL_INTERFACE_FLAG)
    def refresh_project(self, project_id):
        """
        刷新仿真项目配置。当仿真项目的文件更新时，需要刷新仿真项目配置。

        Args:
            project_id: 项目名称

        Returns:
            ProjectConfig: 项目配置信息

        Raises:
            PhotError: 异常代码查看PhotError的exception_code

        Examples:
            >>> project_client.refresh_project("new_project")
        """
        return self.project_manager.refresh_project(project_id)

    @api(Processor.process_new_directory, LOCAL_INTERFACE_FLAG)
    def new_directory(self, directory_path):
        """
        新建文件夹。

        Args:
            directory_path (string): 文件夹路径

        Returns:
            无

        Raises:
            PhotError: 异常代码查看PhotError的exception_code

        Examples:
            >>> project_client.new_directory("C://user//new_project/new_directory")
        """
        self.project_manager.new_directory(directory_path)

    @api(Processor.process_new_file, LOCAL_INTERFACE_FLAG)
    def new_file(self, file_path, file_object):
        """
        新建文件。

        Args:
            file_path: 文件路径
            file_object: 文件对象

        Returns:
            无

        Raises:
            PhotError: 异常代码查看PhotError的exception_code

        Examples:
            >>> file_object = PhotFile(path="C://user//new_project/new_file.txt",
                               name="new_file",
                               type=PhotFileType.OTHER,
                               data=b"Hello world!")
            >>> project_client.new_file("C://user//new_project/new_file.txt", file_object)
        """
        self.project_manager.new_file(file_path, file_object)

    @api(Processor.process_delete_file, LOCAL_INTERFACE_FLAG)
    def delete_file(self, path):
        """
        删除文件或文件夹。

        Args:
            path: 文件或文件夹路径路径

        Returns:
            无

        Raises:
            PhotError: 异常代码查看PhotError的exception_code

        Examples:
            >>> project_client.delete_file("C://user//new_project/new_directory")
        """
        self.project_manager.delete(path)

    @api(Processor.process_save_file, LOCAL_INTERFACE_FLAG)
    def save_file(self, file_path, file_object):
        """
        保存文件。

        Args:
            file_path: 文件路径
            file_object: 文件对象

        Returns:
            无

        Raises:
            PhotError: 异常代码查看PhotError的exception_code

        Examples:
            >>> file_object = PhotFile(path=""C://user//new_project/new_file.txt"",
                               name="new_file",
                               type=PhotFileType.OTHER,
                               data=b"You are welcome to use photlab.")
            >>> project_client.new_file("C://user//new_project/new_file.txt", file_object)
        """
        self.project_manager.save_file(file_path, file_object)
